Go to the first, previous, next, last section, table of contents.

Miscellany

Versioning Standards

In version 7.x.y, x should change only when some documented user-visible aspect of Xconq changes, whether in the interface or kernel. In particular, any additions to GDL, such as a new table or property, require a new x version. y is reserved for bug-fix releases, which can include the implementation of features that were documented but not working correctly or completely.

The macro VERSION should also include a date in parentheses, formatted in "military style", as in "8 Jul 1995". Be sure to set the date to some approximation of the date of your most recent change to the sources.

Coding Standards

The Xconq sources adhere to a number of coding standards that you should follow also. While everyone has their individual style, it is important to the code's maintenance that the existing style be preserved.

You should allocate by using xmalloc. This routine checks for allocation validity and gives a useful error message if allocation fails, it zeroes the block so you can count on the newly allocated space being in a known state, and it collects statistical data, which is important to optimization.

There is one exception to this allocation rule, which is that you may use malloc if you intend to free the memory shortly. An example would be temporary working space needed by an interface. However, you must then check the return result from malloc yourself and handle failures appropriately; remember that players can easily ask for very large games, so it's quite possible that any given call to malloc will be unable to allocate the desired memory.

Always generate a random number by using xrandom. This is a generator of known and consistent properties across all systems that Xconq runs on. Consistency is especially critical for ensuring that networked games stay in sync.

Indent by 4, with tabs at 8. This is effectively what you get in Emacs if you set c-indent-level to 4. System-specific interfaces need not adhere to this rule..

Pitfalls

This chapter would not be complete without some discussion of the traps awaiting the unwary hacker. The Absolute Number One Hazard in hacking Xconq is to introduce code that does not work for all game designs. It is all too easy to assume that, for instance, unit speeds are always less than 20, or airbases can only be built by infantry, or that worlds are always randomly-generated. These sorts of assumptions have caused no end of problems. Code should test preconditions, especially for dynamically-allocated game-specified objects, and it should be tested using the various test scripts in the test directory.

The number two pitfall is to not account for all the possible interfaces. Not all interfaces have a single "current unit" or map window, and some communicate with multiple players or over a network connection.

You should not assume that your hack is generally valid until you have tested it against everything in the library and test directories. The test directory contains scripts that will be useful for this, at least to Unix hackers. See the README in that directory for more information.

Another pitfall is to be sloppy about performance. An algorithm that works fine in a small world with two sides and 50 units may be painfully slow in a large game. Or, the algorithm may allocate too much working space and wind up exhausting memory (this has often happened). You should familiarize yourself with the algorithms already used in Xconq, since they have already been debugged and tuned, and many have been written as generically useful code (see the area-scanning functions in world.c for instance).

If your new feature is expensive, then define a global and compute its value only once, either at the start of the game or when it becomes relevant. Such a global should be named any_<feature>.

Similarly, complicated tests on unit types or sides should be calculated once and cached in a dynamically-allocated array.

You may have noticed that Xconq sources have been liberally sprinkled with debugging code, and you may desire to add some yourself. In this modern age of computing, powerful source-level debuggers are widely available, so there is no good reason to add debugging code to do a job that would be better done by the debugger. Xconq debugging output is generally designed to be useful for understanding average behavior, changes over time, and "high-level transients" such as thrashing in plan or task execution; information that is difficult to collect using only a debugger. When adding new debug output, you should keep this principle in mind. Also, be aware that some of the automated testing scripts enable debug output, so if you add something that is uselessly voluminous, testing output may fill your disk prematurely!

Rationale and Future Directions

This is where I justify what I've done, and not done.

Please note that although Xconq has considerable power, its design was expressly limited to a particular class of two-dimensional board-like strategy games, and that playability is emphasized over generality. For instance, I avoided the temptation to include a general-purpose language, since it opens up many difficult issues and makes it much harder for game designers to produce a desired game (after all, if game designers wanted to use a general-purpose programming language, they could just write C code!). Similarly, full 3D, realtime maneuvering, continuous terrain, and other such goodies must await the truly ultimate game system.

The real problem with a general-purpose language is that although everything is possible, nothing is easy. Many "adventure game writing systems" have fallen into this trap; they end up being poor reimplementations of standard programming languages, and the sole support for adventure gaming amounts to a small program skeleton and a few library functions. It would have been easier just to start with a pre-existing language and just write the skeleton and libraries!

Xconq, on the other hand, provides extensive optimized support for random game setup, large numbers of units, game save/restore, computer opponents, and many other facets of a game. Game designers don't have to deal with the subleties of fractal terrain synthesis, or the ordering of terrain effects on units, or how to tell the computer opponents that airbases are sometimes good for refueling but never any good for transportation, or the myriad of other details that are wired into Xconq. In fact, a complete working game can be set up with less than a half-page of GDL.

Even so, the current Xconq design allows for several layers of extensibility, as was described earlier in this chapter.

There are also several major areas in which Xconq could be improved.

Tables should be supplemented with general formulae, although such formulae will complicate AIs' analyses considerably, since tables are much easier to scan. Formula-based game definition would work much better with AIs that are coded specifically for the game and compiled in; this is more-or-less possible now, but there is not yet a good way to keep AIs from being used in games where they would be inappropriate (it might be amusing to have a panzer general AI attempting to play Gettysburg, but the coding would have to be careful not to try to index nonexistent unit types).

Currently everything is based on a single area of a single world. This could be extended to multiple areas in the world, perhaps at different scales, as well as to multiple worlds. The coding implications are severe, since much of the code mentions x,y alone, with the area implicit. One intermediate solution is to have one area be "active" and shift areas as needed (multiple-level dungeon games work this way).

However, even with its limitations, Xconq has provided, and will continue to provide, many years of enjoyable playing, designing, and hacking. Go to it!


Go to the first, previous, next, last section, table of contents.